package com.zhs.gccs.utils;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;

import com.orhanobut.logger.Logger;



import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Created by heyang on 2017/3/1.
 */

public class ImageUtils {

    public static byte[] bitmap2Bytes(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }

    public static byte[] bitmap2BytesJPG(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        return baos.toByteArray();
    }

    public static Bitmap bytes2Bimap(byte[] b) {
        if (b != null && b.length != 0) {
            return BitmapFactory.decodeByteArray(b, 0, b.length);
        } else {
            return null;
        }
    }

    public static Drawable bitmap2Drawable(Bitmap bitmap) {
        return new BitmapDrawable(bitmap);
    }

    public static Bitmap drawable2Bitmap(Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        } else if (drawable instanceof NinePatchDrawable) {
            Bitmap bitmap = Bitmap
                    .createBitmap(
                            drawable.getIntrinsicWidth(),
                            drawable.getIntrinsicHeight(),
                            drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                                    : Bitmap.Config.RGB_565);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
                    drawable.getIntrinsicHeight());
            drawable.draw(canvas);
            return bitmap;
        } else {
            return null;
        }
    }

    /**
     * byte[] 转 InputStream
     *
     * @param bytes
     * @return
     */
    public static InputStream byte2InputStream(byte[] bytes) {
        return new ByteArrayInputStream(bytes);
    }

    public static byte[] inputStream2Byte(InputStream is) {
        StringBuilder sb = new StringBuilder();
        byte[] readByte = new byte[1024];
        try {
            while (is.read(readByte, 0, readByte.length) != -1) {
                sb.append(new String(readByte).trim());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return sb.toString().getBytes();
    }

    /**
     * 通过图片路径获取Bitmap对象
     *
     * @param path
     * @return
     */
    public static Bitmap getBitmapFromPath(String path) {
        if (TextUtils.isEmpty(path)) {
            return null;
        }

        File file = new File(path);

        if (!file.exists()) {
            Logger.e("拍照的图片路径不存在");
            return null;
        }

        byte[] buf = new byte[1024 * 1024];
        Bitmap bitmap = null;

        try {
            FileInputStream fis = new FileInputStream(path);
            int len = fis.read(buf, 0, buf.length);
            bitmap = BitmapFactory.decodeByteArray(buf, 0, len);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return bitmap;
    }

    public static byte[] compressBitmapForScale(byte[] bytes, int reqWidth, int reqHeight, int maxSize) {
        //600x800
        Bitmap smallBitmap = decodeSampledBitmap(bytes, reqWidth, reqHeight);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int width = smallBitmap.getWidth();
        int height = smallBitmap.getHeight();
        Logger.e("smallBitmap.getWidth=" + width + "\n" +
                "smallBitmap.getHeight=" + height);

        float scaleW = (float) reqWidth / (float) ((width > height) ? height : width);

        if (scaleW >= 1.0f) {
            scaleW = 1.0f;
        }
        Logger.e("scaleW=" + scaleW);

        Matrix matrix = new Matrix();
        matrix.postScale(scaleW, scaleW);

        Bitmap newBitmap = Bitmap.createBitmap(smallBitmap, 0, 0, width, height, matrix, true);
        Logger.e("newBitmap.outWidth=" + newBitmap.getWidth() + "\n" +
                "newBitmap.outHeight=" + newBitmap.getHeight());
//        smallBitmap.recycle();

        int quality = 100;
        newBitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream);
        while (byteArrayOutputStream.toByteArray().length > maxSize) {
            byteArrayOutputStream.reset();
            quality -= 5;
            if (quality <= 5) quality = 5;
            newBitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream);
            if (quality == 5) break;
        }

//        newBitmap.recycle();
        return byteArrayOutputStream.toByteArray();

    }

    //reqWidth 600   reqHeight 800
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        int width = options.outWidth;
        int height = options.outHeight;
        Logger.e("raw.outWidth=" + width + "\n" +
                "raw.outHeight=" + height);

        int inSampleSize = 1;

        if (width > height) {
            if (height > reqWidth) {
                inSampleSize = height / reqWidth;
            }
        } else {
            if (width > reqWidth) {
                inSampleSize = width / reqWidth;
            }
        }

        Logger.e("inSampleSize=" + inSampleSize);

        return inSampleSize;
    }

    public static Bitmap decodeSampledBitmap(byte[] bytes, int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);

        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
    }

    public static Bitmap rotateBitmap(Bitmap origin, float degree) {
        if (origin == null) {
            return null;
        }

        int width = origin.getWidth();
        int height = origin.getHeight();

        Matrix matrix = new Matrix();
        matrix.setRotate(degree);

        Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
        origin.recycle();

        return newBM;
    }

    public static byte[] compressBitmapPng(Bitmap bitmap, int maxSize) {
        int options = 100;
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, options, byteArrayOutputStream);

        Logger.e("length=" + byteArrayOutputStream.toByteArray().length / 1024);

        while (byteArrayOutputStream.toByteArray().length > maxSize) {
            byteArrayOutputStream.reset();
            options -= 5;
            if (options <= 5) {
                options = 5;
            }
            bitmap.compress(Bitmap.CompressFormat.PNG, options, byteArrayOutputStream);
            if (options == 5) {
                break;
            }
        }

        Logger.e("length=" + byteArrayOutputStream.toByteArray().length / 1024 + "\n" +
                "options=" + options);

        return byteArrayOutputStream.toByteArray();
    }

    public static byte[] compressBitmap(Bitmap bitmap, int maxSize) {
        int options = 100;
//        int maxSize = 500 * 1024;//500k
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, options, byteArrayOutputStream);

        Logger.e("length=" + byteArrayOutputStream.toByteArray().length / 1024);

        while (byteArrayOutputStream.toByteArray().length > maxSize) {
            byteArrayOutputStream.reset();
            options -= 5;
            if (options <= 5) {
                options = 5;
            }
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, byteArrayOutputStream);
            if (options == 5) {
                break;
            }
        }

        Logger.e("length=" + byteArrayOutputStream.toByteArray().length / 1024 + "\n" +
                "options=" + options);

        byte[] bytes = byteArrayOutputStream.toByteArray();
        bitmap.recycle();
        return bytes;
    }

    public static Bitmap getBitmapByView(View view) {
        int widthM = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        int heightM = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        view.measure(widthM, heightM);
        int width = view.getMeasuredWidth();
        int height = view.getMeasuredHeight();
//        Logger.e("width=" + width + "\n" + "height=" + height);

        Bitmap bitmap = Bitmap.createBitmap(
                width,
                height,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);

        view.layout(0, 0, width, height);
        view.draw(canvas);
        return bitmap;
    }

    public static Bitmap getImageToChange(Bitmap mBitmap) {
        Bitmap createBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        if (mBitmap != null) {
            int mWidth = mBitmap.getWidth();
            int mHeight = mBitmap.getHeight();
            for (int i = 0; i < mHeight; i++) {
                for (int j = 0; j < mWidth; j++) {
                    int color = mBitmap.getPixel(j, i);
                    int g = Color.green(color);
                    int r = Color.red(color);
                    int b = Color.blue(color);
                    int a = Color.alpha(color);
                    if (g >= 250 && r >= 250 && b >= 250) {
                        a = 0;
                    }
                    color = Color.argb(a, r, g, b);
                    createBitmap.setPixel(j, i, color);
                }
            }
        }
        return createBitmap;
    }

    public static void saveBitmap(Activity activity, Bitmap bitmap, String bitName) {
        String fileName;
        File file;
        if (Build.BRAND.equals("Xiaomi")) { // 小米手机
            fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/" + bitName;
        } else {  // Meizu 、Oppo
            fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/" + bitName;
        }
        file = new File(fileName);

        if (file.exists()) {
            file.delete();
        }
        FileOutputStream out;
        try {
            out = new FileOutputStream(file);
            // 格式为 JPEG，照相机拍出的图片为JPEG格式的，PNG格式的不能显示在相册中
            if (bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)) {
                out.flush();
                out.close();
                // 插入图库
                MediaStore.Images.Media.insertImage(activity.getContentResolver(), file.getAbsolutePath(), bitName, null);
                Toast.makeText(activity, "保存成功", Toast.LENGTH_SHORT).show();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Toast.makeText(activity, "保存失败", Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(activity, "保存失败", Toast.LENGTH_SHORT).show();
        }
        // 发送广播，通知刷新图库的显示
        activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + fileName)));

    }

    public static byte[] getBytes(String filePath) {
        byte[] buffer = null;
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }
}
